package com.skyworth.web.shiro;

import com.skyworth.web.admin.user.domain.UserModel;
import com.skyworth.web.admin.user.service.UserService;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.SubjectContext;
import org.apache.shiro.web.mgt.DefaultWebSubjectFactory;
import org.apache.shiro.web.subject.WebSubjectContext;
import org.apache.shiro.web.subject.support.WebDelegatingSubject;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * @author holin
 * @date 1/8/16.
 */
public class ShiroWebSubjectFactory extends DefaultWebSubjectFactory {

    @Autowired
    private UserService userService;

    @Override
    public Subject createSubject(SubjectContext context) {
        if (!(context instanceof WebSubjectContext)) {
            return super.createSubject(context);
        }


        WebSubjectContext wsc = (WebSubjectContext) context;
        HttpServletRequest request = (HttpServletRequest) wsc.resolveServletRequest();
        String accessToken = request.getHeader("Access-Token");


        if (null != accessToken && accessToken.length() > 0) {
            SecurityManager securityManager = wsc.resolveSecurityManager();
            Session session = wsc.resolveSession();
            boolean sessionEnabled = wsc.isSessionCreationEnabled();

            UserModel user = userService.findUserByAccessToken(accessToken);
            boolean authenticated = true;
            PrincipalCollection principals = null;
            if (null == user) {
                authenticated = false;
            } else {
                principals = new SimplePrincipalCollection(user, "AccessTokenRealm");

                wsc.setPrincipals(principals);

                authenticated = true;

            }

            String host = wsc.resolveHost();
            ServletResponse response = wsc.resolveServletResponse();

            return new WebDelegatingSubject(principals, authenticated, host, session, sessionEnabled,
                    request, response, securityManager);

        }

        return super.createSubject(context);
    }
}
